package com.jianjun.project.system.user;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Method;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.jfinal.core.Path;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.upload.UploadFile;
import com.jianjun.common.constant.HttpStatus;
import com.jianjun.common.util.SecurityUtils;
import com.jianjun.framework.web.domain.AjaxResult;
import com.jianjun.framework.web.interceptor.DataScope;
import com.jianjun.framework.web.page.TableDataInfo;
import com.jianjun.framework.web.render.ExcelWriterRender;
import com.jianjun.project.common.model.SysDept;
import com.jianjun.project.common.model.SysRole;
import com.jianjun.project.common.model.SysUser;
import com.jianjun.project.system.dept.SysDeptService;
import com.jianjun.project.system.post.SysPostService;
import com.jianjun.project.system.role.SysRoleService;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 用户信息
 *
 * @author source
 */
@Path(value = "/system/user")
public class SysUserController extends Controller {
    @Inject
    SysUserService userService;
    @Inject
    SysDeptService deptService;
    @Inject
    SysRoleService roleService;
    @Inject
    SysPostService postService;

    /**
     * 获取用户列表
     */
    @DataScope(deptAlias = "d", userAlias = "u", permission = "system:user:list")
    public void list() {
        SysUser user = JsonKit.parse(getKv().toJson(), SysUser.class);
        Page<SysUser> page = userService.paginate(user);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getList());
        rspData.setTotal(page.getTotalRow());
        renderJson(rspData);
    }

    @DataScope(deptAlias = "d", userAlias = "u", permission = "system:user:export")
    public void export() {
        SysUser user = JsonKit.parse(getKv().toJson(), SysUser.class);
        List<SysUser> list = userService.selectUserList(user);
        List<Map<String, Object>> mapList = list.stream().map(Model::toMap).collect(Collectors.toList());
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(mapList, true);
        render(new ExcelWriterRender(writer, user.getClass().getSimpleName()));
    }

    @DataScope(deptAlias = "d", userAlias = "u", permission = "system:user:query,system:user:add,system:user:edit,system:user:remove")
    public void index() {
        String method = getRequest().getMethod();
        //查询
        if (Method.GET.name().equals(method)) {
            Long userId = getParaToLong();
            AjaxResult ajax = AjaxResult.success();
            if (Objects.nonNull(userId)) {
                userService.checkUserDataScope(userId);
                SysUser sysUser = userService.selectUserById(userId);
                ajax.put(AjaxResult.DATA_TAG, sysUser);
                ajax.put("postIds", postService.selectPostIdListByUserId(userId));
                ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
            }
            List<SysRole> roles = roleService.selectRoleAll();
            ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
            ajax.put("posts", postService.selectPostAll());
            renderJson(ajax);
        }
        //新增
        if (Method.POST.name().equals(method)) {
            SysUser user = JsonKit.parse(getRawData(), SysUser.class);
            deptService.checkDeptDataScope(user.getDeptId());
            roleService.checkRoleDataScope(user.getRoleIds());
            if (!userService.checkUserNameUnique(user)) {
                renderJson(AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在"));
                return;
            } else if (StrUtil.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
                renderJson(AjaxResult.error("新增用户'" + user.getUserName() + "'失败，手机号码已存在"));
                return;
            } else if (StrUtil.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
                renderJson(AjaxResult.error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在"));
                return;
            }
            user.setCreateBy(SecurityUtils.getUsername());
            user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
            renderJson(AjaxResult.success(userService.insertUser(user)));
        }
        //修改
        if (Method.PUT.name().equals(method)) {
            SysUser user = JsonKit.parse(getRawData(), SysUser.class);
            userService.checkUserAllowed(user);
            userService.checkUserDataScope(user.getUserId());
            deptService.checkDeptDataScope(user.getDeptId());
            roleService.checkRoleDataScope(user.getRoleIds());
            if (!userService.checkUserNameUnique(user)) {
                renderJson(AjaxResult.error("修改用户'" + user.getUserName() + "'失败，登录账号已存在"));
                return;
            } else if (StrUtil.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
                renderJson(AjaxResult.error("修改用户'" + user.getUserName() + "'失败，手机号码已存在"));
                return;
            } else if (StrUtil.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
                renderJson(AjaxResult.error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在"));
                return;
            }
            user.setUpdateBy(SecurityUtils.getUsername());
            renderJson(AjaxResult.success(userService.updateUser(user)));
        }
        //删除
        if (Method.DELETE.name().equals(method)) {
            Long[] userIds = Convert.toLongArray(getPara());
            if (ArrayUtil.contains(userIds, SecurityUtils.getUserId())) {
                renderJson(AjaxResult.error("当前用户不能删除"));
                return;
            }
            userService.deleteUserByIds(userIds);
            renderJson(AjaxResult.success());
        }
    }

    /**
     * 重置密码
     */
    @DataScope(permission = "system:user:resetPwd")
    public void resetPwd() {
        SysUser user = JsonKit.parse(getRawData(), SysUser.class);
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(SecurityUtils.getUsername());
        renderJson(AjaxResult.ajax(userService.resetPwd(user)));
    }


    /**
     * 状态修改
     */
    @DataScope(permission = "system:user:edit")
    public void changeStatus() {
        SysUser user = JsonKit.parse(getRawData(), SysUser.class);
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setUpdateBy(SecurityUtils.getUsername());
        renderJson(AjaxResult.ajax(userService.updateUserStatus(user)));
    }


    /**
     * 根据用户编号获取授权角色
     */
    @DataScope(deptAlias = "d", permission = "system:user:query,system:user:edit")
    public void authRole() {
        String method = getRequest().getMethod();
        //查询
        if (Method.GET.name().equals(method)) {
            Long userId = getParaToLong();
            AjaxResult ajax = AjaxResult.success();
            SysUser user = userService.selectUserById(userId);
            List<SysRole> roles = roleService.selectRolesByUserId(userId);
            ajax.put("user", user);
            ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
            renderJson(ajax);
        }
        //修改
        if (Method.PUT.name().equals(method)) {
            Long userId = getParaToLong("userId");
            Long[] roleIds = getParaValuesToLong("roleIds");
            userService.checkUserDataScope(userId);
            roleService.checkRoleDataScope(roleIds);
            userService.insertUserAuth(userId, roleIds);
            renderJson(AjaxResult.success());
        }
    }


    /**
     * 获取部门树列表
     */
    @DataScope(deptAlias = "d", permission = "system:user:list")
    public void deptTree() {
        SysDept dept = JsonKit.parse(getKv().toJson(), SysDept.class);
        renderJson(AjaxResult.success(deptService.selectDeptTreeList(dept)));
    }

    @DataScope(deptAlias = "d", permission = " system:user:import")
    public void importData() {
        UploadFile file = getFile("file");
        boolean updateSupport = getBoolean("updateSupport");
        ExcelReader reader = ExcelUtil.getReader(file.getFile());
        List<SysUser> userList = reader.readAll().stream().map(m -> new SysUser()._setAttrs(m)).collect(Collectors.toList());
        String operName = SecurityUtils.getUsername();
        String message = userService.importUser(userList, updateSupport, operName);
        renderJson(AjaxResult.success(message));
    }


    public void importTemplate() {
        List<SysUser> list = ListUtil.toList(SecurityUtils.getLoginUser().getUser());
        List<Map<String, Object>> mapList = list.stream().map(m -> m.remove("password").toMap()).collect(Collectors.toList());
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(mapList, true);
        render(new ExcelWriterRender(writer, SysUser.class.getSimpleName()));
    }
}
